對於工程師來說選擇用什麼樣的技術,背後都是取決於商業策略需要什麼,以常見的 SSR (Server Side Rendering)、pre-rendering 來說,為什麼要做 SSR 跟 pre-rendering,不外乎是希望網站整體的 SEO 能夠變好,或是提升使用者體驗。
而現在 SPA (Single Page Application) 盛行的時代,許多網站在沒有框架或後端支援的情況下,僅僅使用像是 React 或 Vue 等前端框架,要做到 SSR 或 pre-rendering 還需要做許多設定,做這些技術研究都得花費時間成本與心思,最後才能導入到專案中。
所以 Next.js 的出現能夠解決工程師心中的痛,不必再花費很多時間處理 pre-rendering 或 SSR 的問題,而是利用框架的優勢,讓工程師更專注在開發核心功能上面。
Next.js 是一個基於 React 的框架,它同時支援 SSR (Server Side Rendering) 與 SSG (Static Side Generation) 兩種方法,不需要很多的設定就可以讓網站同時有這兩種功能。
Next.js 在設計上可以混用兩種方法,像是 /page-a
希望能夠 SSR,因為網站內容很常改變,需要 API 支援變動頻繁的資料;而 /page-b
則是使用 SSG 則是可以用在內容較不常改變的頁面,例如 Landing Page 或部落格等。
SEO 除了需要網站內容之外,還必須提到 core web vitals 的評分,評分的標準包括網站的速度、是否使用較新的圖片格式等等,因此網站可能會選用 WebP 的檔案格式。WebP 這種格式根據 google 的無失真壓縮測試,甚至可以比 PNG 檔少了 45% 的檔案大小。想要使用這種檔案格式,想要自動化處理,就必須使用 webpack 或 gulp 等加入一些 plugin 進行處理,不僅設定麻煩,事後還要維護不少的設定檔,可以看作是一項不小的成本。
而 Next.js 也提供了相對應的解決方案,可以使用內建的圖片優化方案,讓 Next.js 幫我們自動化處理圖片的格式,不用再額外安裝插件生成不同的格式的圖片檔,而且可以根據不同的瀏覽器,提供支援的圖片檔案,能夠減少許多繁冗的程式碼。
Next.js 實際上是一個全端框架,它除了 React 的部分外,甚至還提供了建立 API 的功能。如果一個新的專案,在還沒有建構 API 的服務之前,考慮使用 Next.js 的 API routes 是一個選項。
看了基本的 Next.js 介紹,你也許在思考導入新技術的風險,大家導入一項新技術的擔憂,其中一項便是資料來源不夠多,在查詢問題解決方法時,因為沒有足夠大的社群資源,導致得自己想破頭可能也找不到解答。但從使用 Next.js 使用人數上每個月都有線性成長,至今為止,每週已經有 100 多萬人下載,GitHub 的星星數也到了 70K。
https://www.npmtrends.com/next
此外,有需多著名的公司都已經採用了 Next.js 的解決方案,像是 TikTok、Netflix、GitHub、Uber、Twitch 等等。
Companies / Sites using Next.js · Discussion #10640 · vercel/next.js
綜合上述,Next.js 這個框架已經漸漸成熟,社群、資源都以很快的速度增加,所以導入後不用擔心框架的討論度不夠,導致資訊尋找困難。
說了這麼多,第二天不寫點程式好像說不過去,那我們就來簡單玩一下 Next.js 吧!
如同我們在使用 react 時經常會用到的 create-react-app
, Next.js 也有方便的 CLI 工具 create-next-app
可以使用,它能夠快速建立一個基本的應用,並且包含了許多你可能會用到的工具、設定,像是 eslint
、 .gitignore
等。如果你需要不同的 template,在 Next.js 官方的 repo 中也有各式各樣的範例可以在使用 create-next-app
時引用。
接下來,你可以使用以下的指令建立 next app:
npx create-next-app
# or
yarn create next-app
而如果你需要 typescript 支援的話,則可以在指令後加上 --ts
或 --typescript
的設定:
npx create-next-app --ts
# or
yarn create next-app --typescript
在建立完 Next.js 的專案後,我們來啟動 Next.js 的應用吧!使用以下指令開啟 dev server:
# started server on http://localhost:3000
yarn dev
然後,開啟瀏覽器輸入「http://localhost:3000」,你便可以看到這個專案的預設首頁。
如果只是啟動專案好像少了點什麼,所以就讓我們來看一下 Next.js 的資料夾架構跟一些檔案設定吧!
這個資料夾底下放的是 Next.js 應用中的頁面,因為 Next.js 是使用 file-based routing,所以我們會把所有的頁面都放在裡面,而詳細介紹會在後面的章節中提到。
如果你的 next app 有些客製化的需求,則可以在這個檔案中設定,以下以環境變數作為舉例。
我們經常會在程式碼中使用環境變數,而常見的做法是會建立一個 .env
檔案,然後再搭配 dotenv
之類的套件使用環境變,而 Next.js 的作法則是可以在 next.config.js
中定義我們需要的環境變數。
在 next.config.js
加入以下設定:
module.exports = {
env: {
apiKey: 'api-key',
},
}
接下來,你就可以 react 中使用 process.env.apiKey
:
function Home() {
return <h1>環境變數 apiKey: {process.env.apiKey}</h1>;
}
export default Home;
next.config.js
的客製化設定挺豐富的,包括像是可以設定檔案讀取的路徑 base path,客製化的 header ,或是 webpack 的設定 等,如果有需要這些設定的話,可以到官方網站中看看。
next-env.d.ts
這個檔案則是用在 typescript 型別的引用,這個檔案預設產生的內容如下:
/// <reference types="next" />
/// <reference types="next/types/global" />
接下來我們來看這個檔案的用途,首先,這個檔案中使用 typescript 的 triple-slash directives,引用了 Next.js 所定義的型別。再看到 tsconfig.json
中的 include
包含了這個檔案,所以你現在知道,這個檔案會參與 typescript 的編譯過程。
然後你再看到 styles
這個資料夾底下包含兩個檔案:
globals.css
Home.module.css
這是 Next.js 的其中一個預設的功能,不用額外設定就支援 CSS 檔案跟 CSS Modules。而之所以 typescript 讀得懂 *.module.css
的檔案也是因為有 next-env.d.ts
。
我們來實驗一下,把 next-env-d.ts
的第二行刪掉後,到 pages/index.tsx
中看看,你會看到 typescript 無法解析像是 Home.module.css
這種檔案。
所以,我們來看看第二行的型別引用包含了什麼,到 node_modules/next/types/global.d.ts
中看看裡面的型別定義,你可以看到裡面宣告了三個 module:
declare module '*.module.css' { ... }
declare module '*.module.sass' { ... }
declare module '*.module.scss' { ... }
正是因為有了這三個 declare module
,才能在專案中讓 typescript 能夠辨別 CSS modules。
而第一行的型別引用跟第二行差不多,第一行則是讓我們可以使用 <html amp="">
、 <link nonce="">
、 <style jsx>
等的語法。
像是 :
.eslintrc
:為了讓程式碼品質更為穩定,大部分專案都會使用的 lint 套件.gitignore
:這個檔案會設定一些你不想加入版控的檔案,例如 /node_modules
tsconfig.json
:這個檔案則是用在 typescript 編譯時需要的設定剩下的檔案較為瑣碎就不再細說了。
在這個章節我們了解到 Next.js 提供許多很棒的功能,包含了混用 SSR (Server Side Rendering) 跟 SSG (Static Side Generation) 的特性,而且還支援基於 TypeScript 開發,還有令人興奮的圖片優化,在支援 WebP 的瀏覽器中使用這種較新的檔案格式。
表面上是因為這些豐富的特性,有利於 SEO 與 UX,對於工程師來說,使用 Next.js 則是可以提升 DX (developer Experience),簡化 SSR 與 pre-rendering 的設定,寫法與原本的 React 寫法很接近,能夠以較低的成本學習並導入到專案中。而且資源未來還會陸續增多,暫且不必擔心框架的熱度影響導入後找不到解決問題的方法。
在瞭解了 Next.js 的一些功能後,透過建立一個應用並快速導覽,我們也知道 Next.js 的專案架構以及一些設定檔的用途。
這只是剛開始而已,接下來 28 天就讓我們一起來看看 Next.js 的魔力吧!